package com.signway.harmony_demo.slice;

import com.signway.harmony_demo.ResourceTable;
import com.signway.harmony_demo.point.DrawPoint;
import com.signway.harmony_demo.point.MyPoint;
import com.signway.harmony_demo.slice.base.BaseAbilitySlice;
import com.signway.harmony_demo.utils.CommonData;
import com.signway.harmony_demo.utils.LogUtil;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.Text;
import ohos.app.Context;
import ohos.bundle.ElementName;
import ohos.event.commonevent.*;
import ohos.rpc.*;

import java.util.List;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

public class MathDrawRemSlice extends BaseAbilitySlice {
    public static final String TAG = CommonData.TAG + MathDrawRemSlice.class.getSimpleName();
    private Context context = null;
    private boolean isLocal = true;
    private float[] pointXs;
    private float[] pointYs;
    private IRemoteObject remoteObject;
    private DependentLayout area;
    private MathRemoteProxy proxy;
    private boolean[] isLastPoints;
    private MyCommonEventSubscriber subscriber;
    private DrawPoint drawl;

    @Override
    protected void onStart(Intent intent) {
        LogUtil.info(TAG, "onStart");
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_math_draw);
        initAndConnectDevice(intent);
        initDraw();
        subscribe();
    }

    private void initDraw() {
        area = (DependentLayout) findComponentById(ResourceTable.Id_bac_area);
        drawl = new DrawPoint(this, isLocal);
        drawl.setWidth(MATCH_PARENT);
        drawl.setHeight(MATCH_PARENT);
        area.addComponent(drawl);
        drawl.setOnDrawBack( points -> { drawPoint(points); } );
    }

    private void drawPoint(List<MyPoint> points) {
        if (points != null && points.size() > 1) {
            pointXs = new float[points.size()];
            pointYs = new float[points.size()];
            isLastPoints = new boolean[points.size()];
            for (int i = 0; i < points.size(); i++) {
                pointXs[i] = points.get(i).getPositionX();
                pointYs[i] = points.get(i).getPositionY();
                isLastPoints[i] = points.get(i).isLastPoint();
            }

            // After the drawing is completed, send the data to the remote
            if (remoteObject != null && proxy != null) {
                try {
                    proxy.senDataToRemote(MathRemoteProxy.REQUEST_SEND_DATA);
                } catch (RemoteException e) {
                    LogUtil.info(TAG, "processEvent RemoteException");
                }
            }
        }
    }

    private void subscribe() {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(CommonData.MATH_DRAW_EVENT);
        matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_SCREEN_ON);
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        subscriber = new MyCommonEventSubscriber(subscribeInfo);
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            LogUtil.error("", "subscribeCommonEvent occur exception.");
        }
    }

    private void initAndConnectDevice(Intent intent) {
        context = MathDrawRemSlice.this;
        String remoteDeviceId = intent.getStringParam(CommonData.KEY_REMOTE_DEVICE_ID);
        isLocal = intent.getBooleanParam(CommonData.KEY_IS_LOCAL, false);
        Text text = (Text) findComponentById(ResourceTable.Id_text_title);
        text.setText(isLocal ? "本地端" : "远程端");

        connectRemotePa(remoteDeviceId);
    }

    private void connectRemotePa(String deviceId) {
        if (deviceId.isEmpty())
            return;
        Intent connectPaIntend = new Intent();
        Operation operation = new Intent.OperationBuilder()
//                .withDeviceId(deviceId)
//                .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                .withBundleName(getBundleName())
                .withAbilityName(CommonData.MATH_GAME_SERVICE_NAME)
                .build();
        connectPaIntend.setOperation(operation);

        IAbilityConnection conn = new IAbilityConnection() {
            @Override
            public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
                LogUtil.info(TAG, "onAbilityConnectDone.......");
                connectAbility(elementName, iRemoteObject, i);
            }

            @Override
            public void onAbilityDisconnectDone(ElementName elementName, int i) {
                LogUtil.info(TAG, "onAbilityDisconnectDone......");
                disconnectAbility(this);
            }
        };
        context.connectAbility(connectPaIntend, conn);
    }

    private void connectAbility(ElementName elementName, IRemoteObject iRemoteObject, int i) {
        remoteObject = iRemoteObject;

    }

    class MathRemoteProxy implements IRemoteBroker {
        private static final int ERR_OK = 0;

        private static final int REQUEST_START_ABILITY = 1;

        private static final int REQUEST_SEND_DATA = 2;

        private final IRemoteObject remote;

        public MathRemoteProxy(IRemoteObject remote) {
            this.remote = remote;
        }

        @Override
        public IRemoteObject asObject() {
            return remote;
        }

        public void senDataToRemote(int requestType) throws RemoteException {
            LogUtil.info(TAG, "send data to local draw service");
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
            try {
                if (pointXs != null && pointYs != null && isLastPoints != null) {
                    data.writeFloatArray(pointXs);
                    data.writeFloatArray(pointYs);
                    data.writeBooleanArray(isLastPoints);
                }
                remote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    LogUtil.error(TAG, "RemoteException:");
                }
            } catch (RemoteException e) {
                LogUtil.error(TAG, "RemoteException:" + e.toString());
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }
    }

    class MyCommonEventSubscriber extends CommonEventSubscriber {
        MyCommonEventSubscriber(CommonEventSubscribeInfo info) {
            super(info);
        }
        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            Intent intent = commonEventData.getIntent();
            pointXs = intent.getFloatArrayParam(CommonData.KEY_POINT_X);
            pointYs = intent.getFloatArrayParam(CommonData.KEY_POINT_Y);
            isLastPoints = intent.getBooleanArrayParam(CommonData.KEY_IS_LAST_POINT);
            drawl.setDrawParams(isLastPoints, pointXs, pointYs);
            LogUtil.info(TAG, "onReceiveEvent.....");
        }
    }
}
